﻿// owner 蒋家伟
#include "Socket.h"

// qt
#include <QThread>

// jsdk
#include "Dbg_Warn_Define.h"

using namespace jsdk;

jsdk::Socket::Socket()
{
}

OwnerPtr<Socket> jsdk::Socket::create(ISocketEventHandler * pSocketEventHandler)
{
    OwnerPtr<Socket> opSocket = NEW_AS_OWNERPTR(Socket);

    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opSocket, L"Socket对象创建失败", L"蒋家伟", L"2023-07-26");
    opSocket->m_opSocketWorker.swap(SocketWorker::create(pSocketEventHandler));
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opSocket->m_opSocketWorker, L"Socket工作对象创建失败", L"蒋家伟", L"2023-07-26");

    opSocket->m_opThread.swap(NEW_AS_OWNERPTR_WITH_DELETER(QThread, ThreadDeleter));
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opSocket->m_opThread, L"Socket工作线程创建失败", L"蒋家伟", L"2023-07-26");

    return std::move(opSocket);
}

bool jsdk::Socket::init() const
{
    // 跨线程信号与槽连接
    bool success = connect(this, SIGNAL(connectSocket(QString, qint64)), m_opSocketWorker.get(), SLOT(onConnect(QString, qint64)));
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(success, L"套接字连接信号与槽创建失败", L"蒋家伟", L"2023-07-26");

    success = connect(this, SIGNAL(sendMessage(QByteArray, qint64)), m_opSocketWorker.get(), SLOT(onSend(QByteArray, qint64)));
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(success, L"套接字发送信号与槽创建失败", L"蒋家伟", L"2023-07-26");

    // Worker解码完毕后反馈
    return success;
}

void jsdk::Socket::connected(const std::string& ip, qint64 port)
{
    DBG_WARN_AND_RETURN_VOID_UNLESS(m_opSocketWorker && !m_opSocketWorker->isOnLine(), L"当前socket工作对象没有创建成功或者正在工作", L"蒋家伟", L"2023-07-26");
    DBG_WARN_AND_RETURN_VOID_UNLESS(m_opThread, L"线程对象创建失败", L"蒋家伟", L"2023-07-26");

    bool success = init();
    DBG_WARN_AND_RETURN_VOID_UNLESS(success, L"套接字对象信号与槽连接失败", L"蒋家伟", L"2023-07-26");

    m_opSocketWorker->moveToThread(m_opThread.get());
    m_opThread->start();

    // 发给Worker
    emit connectSocket(QString::fromStdString(ip), port);
}

void jsdk::Socket::send(std::string&& msg, qint64 length) const
{
    DBG_WARN_UNLESS(m_opSocketWorker && m_opSocketWorker->isOnLine(), L"当前socket工作对象没有创建成功或者没有在工作", L"蒋家伟", L"2023-07-26");
    // 发给Worker
    emit sendMessage(QByteArray(msg.c_str(), length), length);
}

void jsdk::Socket::reconnect(const std::string& ip, int64_t port) const
{
    DBG_WARN_AND_RETURN_VOID_UNLESS(m_opSocketWorker && !m_opSocketWorker->isOnLine(), L"当前socket工作对象没有创建成功或者正在工作", L"蒋家伟", L"2023-07-26");
    DBG_WARN_AND_RETURN_VOID_UNLESS(m_opThread, L"线程对象创建失败", L"蒋家伟", L"2023-07-26");

    // 发给Worker
    emit connectSocket(QString::fromStdString(ip), port);
}

bool jsdk::Socket::isOnLine() const
{
    return m_opSocketWorker && m_opSocketWorker->isOnLine();
}